#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

int main() {
    int fd;
    struct stat sb;
    char *mapped;
    const char *filename = "test.txt";

    // 1. 打开文件
    fd = open(filename, O_RDWR | O_CREAT, 0644);
    if (fd == -1) {
        perror("open failed");
        exit(EXIT_FAILURE);
    }

    // 2. 获取文件大小（若文件为空，先扩展大小）
    if (fstat(fd, &sb) == -1) {
        perror("fstat failed");
        close(fd);
        exit(EXIT_FAILURE);
    }
    // 如果文件为空，设置大小为1024字节
    if (sb.st_size == 0) {
        if (ftruncate(fd, 1024) == -1) {
            perror("ftruncate failed");
            close(fd);
            exit(EXIT_FAILURE);
        }
        // 重新获取文件大小
        fstat(fd, &sb);
    }

    // 3. 映射文件到内存
    mapped = (char*)mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (mapped == MAP_FAILED) {
        perror("mmap failed");
        close(fd);
        exit(EXIT_FAILURE);
    }

    // 4. 操作内存（等价于操作文件）
    printf("原内容: %.*s\n", (int)sb.st_size, mapped);

    // 写入新内容（注意不要超过映射长度）
    const char *new_data = "Hello, mmap!";
    strncpy(mapped, new_data, strlen(new_data));
    printf("写入后内容: %.*s\n", (int)sb.st_size, mapped);

    // 5. 解除映射
    if (munmap(mapped, sb.st_size) == -1) {
        perror("munmap failed");
        close(fd);
        exit(EXIT_FAILURE);
    }

    // 6. 关闭文件
    close(fd);
    return 0;
}
